﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Newtonsoft.Json;
using Geometry;
using ReBot.API;


namespace Rebot
{
    [Rotation("Holy Spirit v1.1", "Dupe", WoWClass.Priest, Specialization.PriestHoly, 30)]
    public class HolySpiritSpec110 : CombatRotation
    {
        //-- in game selection options
        [JsonProperty("Levitate? yes or no   ")]
        public bool levitate_player = false;
        [JsonProperty("Use Angelic Feather?  ")]
        public bool Use_AngelicFeather = false;
        [JsonProperty("Use Halo?             ")]
        public bool Use_Halo = false;
        [JsonProperty("Dispel Group?        ")]
        public bool Dispel_Group = false;
        //-- in game selection otions end

        //-- talent detection deffinition                    
        public bool Desperate_Prayer = false;
        public bool Spectral_guise = false;
        public String AngelicBalwark = "Passive";
        public String Body_and_soul = "Passive";
        public bool Angelic_Feather = false;
        public bool Phantasm_Talent = false;
        public String Surge_of_light = "Passive";
        public bool Mindbender = false;
        public bool Power_Word_Solace = false;
        public bool Void_Tendrils = false;
        public bool Psychic_Scream = false;
        public String Dominate_Mind = "Not implemented";
        public String Twist_of_Fate = "Passive";
        public bool Power_Infusion = false;
        public bool Spirit_Shell = false;
        public bool Cascade_talent = false;
        public bool Divine_Star = false;
        public bool Halo_talent = false;
        public bool Clarity_of_Purpose = false;
        public String Words_of_Mending = "Passive";
        public bool Saving_Grace = false;
        //-- in game talent detection 

        //------Settings Finish

        public bool Debug = true;

        //Writes to log
        private void DebugWrite(string text)
        {
            if (Debug) API.Print(text);
        }
        // Debug log end
        public HolySpiritSpec110()
        {
            //Tier 1 Talents Detected -----
            if (HasSpell(19236))//Desperate Prayer
            {
                Desperate_Prayer = true;
                DebugWrite("Desperate Prayer tier 1 = " + Desperate_Prayer);
            }
            else if (HasSpell(112833))//Spectual guise
            {
                Spectral_guise = true;
                DebugWrite("Specual guise Tier 1 = " + Spectral_guise);
            }
            //Tier 1 end
            //Tier 2 Detected ---------
            if (HasSpell(121536))//Angelic Feather
            {
                Angelic_Feather = true;
                DebugWrite("Angelic Feather tier 2 = " + Angelic_Feather);
            }
            else if (HasSpell(108942))//Phantasm
            {
                Spectral_guise = true;
                DebugWrite("Phantasm Tier 2 = " + Phantasm_Talent);
            }
            //Tier 2 end
            //Tier 3 Detected ----------
            if (HasSpell(123040))//Mindbender
            {
                Mindbender = true;
                DebugWrite("Mindbender Tier 3 = " + Mindbender);
            }
            else if (HasSpell(129250))//Powerword: Solace
            {
                Power_Word_Solace = true;
                DebugWrite("Power Word: Solace Tier 3 = " + Power_Word_Solace);
            }
            //Tier 3 end
            //Tier 4 Detected -------------
            if (HasSpell(108920))//Void Tendrils
            {
                Void_Tendrils = true;
                DebugWrite("Void Tendrils Tier 4 = " + Void_Tendrils);
            }

            //Tier 4 end
            //Tier 5 Detected -------------
            if (HasSpell(10060))//Power Infusion
            {
                Power_Infusion = true;
                DebugWrite("Power Infusion Tier 5 = " + Power_Infusion);
            }
            else if (HasSpell(109964))//Spirit Shell
            {
                Spirit_Shell = true;
                DebugWrite("Spirit Shell Tier 5 = " + Spirit_Shell);
            }
            //Tier 5 end
            //Tier 6 Detected -------------
            if (HasSpell(121135))//Cascade
            {
                Cascade_talent = true;
                DebugWrite("Cascade Tier 6 = " + Cascade_talent);
            }
            else if (HasSpell(110744))//Divine Star
            {
                Divine_Star = true;
                DebugWrite("Divine Star Tier 6 = " + Divine_Star);
            }
            else if (HasSpell(120517))//Halo
            {
                Halo_talent = true;
                DebugWrite("Halo Tier 6 = " + Divine_Star);
            }
            //Tier 6 end
            //Tier 7 Detected ------------
            if (HasSpell(155245))//Clarity of Purpose
            {
                Clarity_of_Purpose = true;
                DebugWrite("Clarity of Purpose Tier 7 = " + Clarity_of_Purpose);
            }
            else if (HasSpell(152116))//Saving Purpose
            {
                Saving_Grace = true;
                DebugWrite("Saving Grace Tier 7 = " + Saving_Grace);
            }
            //Tier 7 end

            GroupBuffs = new string[]
			{
				"Power Word: Fortitude"
			};
            PullSpells = new string[]
			{
				"Smite",
			};
        }

    
        //Target indicator start
        public bool Targeted()
        {
            if (Me.Target != null)
            {
                if (Me.Target.IsEnemy)
                {
                    return true;
                }
                else if (!Me.Target.IsEnemy)
                {
                    return false;    
                }
            }
            return false;
        }
        // Target indicator end
       

        //-----------------------------------Out of Combat start
        public override bool OutOfCombat()
        {
            
            if (CastSelf("Power Word: Fortitude", () => !HasAura("Power Word: Fortitude"))) return true;
            if (CastSelf("Chakra: Sanctuary", () => !HasAura("Chakra: Sanctuary") && SpellCooldown("Chakra: Sanctuary") < 0)) return true;
            //-----------------Angelic Feather Talent start
            if (Angelic_Feather == true && Use_AngelicFeather == true)
            {
                AngelicFeather();
            }
            //------------------Angelic Feather talent end
            if (Targeted() == true)
            {
                Cast("Shadow Word: Pain", () => Me.HealthFraction > 0.7 && Me.Target != null && Me.Target.IsEnemy, Me.Target);
            }
            List<PlayerObject> groupmembers = Group.GetGroupMemberObjects();
            List<PlayerObject> Tanks = groupmembers.FindAll(x => x.IsTank && x.IsInCombatRangeAndLoS);
            PlayerObject Tank1 = Tanks.FirstOrDefault();
            if (Tank1 != null && Tank1.InCombat && Me.Target != null)
                {
                    if (CastPreventDouble("Power Word: Shield", () => !Tank1.HasAura("Weakened Soul") && Tank1.IsInCombatRangeAndLoS && !Tank1.IsDead, Tank1, 1000)) return true;
                }
                 if (Me.Target != null && Me.HealthFraction <= 0.7 || Tank1 != null && Me.Target != null)
                {
                    Healer();
                    return true;
                }
                 Cast("Shadow Word: Pain", ()=> Me.HealthFraction > 0.7 && Me.Target != null && Me.Target.IsEnemy && !Me.Target.IsDead);
                
               
                 

            return base.OutOfCombat();
        }
        //-----------------------------------Out of combat end
        
       

        public override void Combat()
        {

            if (!Target.IsEnemy || CombatMode == CombatModus.Healer || Me.InCombat && Me.IsTargetingMeOrPets == true || CombatRole.Equals(CombatRole.DPS) && Me.Target == Me || Me.Target.DisplayId == 49312)
            {
           
                Healer();

            }
            else
            {
                DPS();

            }
            //Dummy zapping
            if (Target.DisplayId == 28048 || Target.DisplayId == 27510)
            {
                DPS();
            }
            return;
            throw new NotImplementedException();
        }

        public void Healer()
        {
            if (HasGlobalCooldown() == true)
                return;
            
            List<PlayerObject> members = Group.GetGroupMemberObjects();
            if (members.Count > 0 || Targeted() == true)
            {
                List<PlayerObject> Tanks = members.FindAll(x => x.IsTank && x.IsInCombatRange && !x.IsDead);
                List<PlayerObject> GrpHeal1 = members.FindAll(x => x.HealthFraction <= 0.7 && x.IsInCombatRange && !x.IsDead);
                List<PlayerObject> GrpHeal2 = members.FindAll(x => x.HealthFraction <= 0.7 && x.IsInCombatRange && !x.IsDead);
                PlayerObject healtest = GrpHeal2.FirstOrDefault(x => !x.IsDead && x.IsInCombatRange);
                PlayerObject Tank1 = Tanks.FirstOrDefault();

                //---------------------------------Group Healing Start
                if (GrpHeal1.Count > 2)
                {
                    if (Halo_talent == true && Use_Halo == true)
                    {
                        Halo();
                    }
                    else if (Cascade_talent == true)
                    {
                        Cascade();
                    }

                }
                if (GrpHeal2.Count > 3)
                {
                    if (Tank1 != null)
                    {
                        if (Tank1.HealthFraction > healtest.HealthFraction)
                        {
                            Cast("Circle of Healing", () => !Target.IsDead && Target.IsInCombatRange && SpellCooldown("Circle of Healing") < 0, GrpHeal2.FirstOrDefault());

                            Cast("Prayer of Healing", GrpHeal2.FirstOrDefault(), ()=> Clarity_of_Purpose == false );
                            Cast("Clarity of Purpose", GrpHeal2.FirstOrDefault(), () => Clarity_of_Purpose == true);
                        }
                    }
                }
                //----------------------------------Group Healing End
                //---------------Main Tank Healing Start
                if (Tank1 != null && Tank1.IsInCombatRange && Tank1.HealthFraction < 0.99)
                {
                    Cast("Power Word: Shield", Tank1, () => !Tank1.HasAura("Weakened Soul") && !Tank1.HasAura("Power Word: Shield") && Tank1.IsInCombatRange && !Tank1.IsDead);
                    CastOnTerrain("Holy Word: Sanctuary", Tank1.PositionPredicted, () => SpellCooldown("Holy Word: Sanctuary") < 0);
                    Cast("Flash Heal", () => Me.HasAura("Surge of light"), Tank1);
                    Cast("Renew", () => Tank1.HealthFraction < 0.9 && !Tank1.HasAura("Renew"), Tank1);
                    Cast("Prayer of Mending", () => !Tank1.HasAura("Prayer of Mending") && Tank1.IsInCombatRange && !Tank1.IsDead, Tank1);
                    Cast("Flash Heal", () => Tank1.HealthFraction < 0.4, Tank1);
                    Cast("Binding Heal", () => Tank1.HealthFraction < 0.8 && Me.HealthFraction < 0.8, Tank1);
                    Cast("Heal", () => Tank1.HealthFraction < 0.8, Tank1);
                }
                //---------------Main Tank Healing End
                //---Second Tank Healing Start
                if (Tanks.Count > 1)
                {
                    PlayerObject Tank2 = Tanks.Last();
                    if (Tank2 != null && Tank1.IsInCombatRangeAndLoS && Tank2.HealthFraction < 0.99)
                    {
                        Cast("Power Word: Shield", Tank2, () => !Tank2.HasAura("Weakened Soul") && !Tank2.HasAura("Power Word: Shield") && Tank2.IsInCombatRange && !Tank2.IsDead);
                        Cast("Flash Heal", () => Tank2.HealthMissing < 10000 || Me.HasAura("Surge of light"), Tank2);
                        CastPreventDouble("Renew", () => Tank2.HealthFraction < 0.9 && !Tank2.HasAura("Renew"), Tank2);
                        CastPreventDouble("Flash Heal", () => Tank2.HealthFraction < 0.4, Tank2);
                        CastPreventDouble("Binding Heal", () => Tank2.HealthFraction < 0.8 && Me.HealthFraction < 0.8, Tank2);
                        CastPreventDouble("Heal", () => Tank2.HealthFraction < 0.9, Tank2);
                    }
                }
                //---Second Tank Healing end

                foreach (var player in Group.GetGroupMemberObjects().Where(x => x.HealthFraction < 0.9))
                {
                    Cast("Power Word: Shield", player, () => !player.HasAura("Weakened Soul") && !player.HasAura("Power Word: Shield") && player.IsInCombatRange && !player.IsDead);
                    Cast("Flash Heal", () => player.HealthMissing < 10000 || Me.HasAura("Surge of light"), player);
                    Cast("Renew", () => player.HealthFraction < 0.9 && !player.HasAura("Renew"), player);
                    Cast("Binding Heal", player, () => player.HealthFraction < 0.8 && Me.HealthFraction < 0.8);
                    Cast("Flash Heal", player, () => !player.IsTank && !player.IsDead && player.HealthFraction < 0.5 && !player.IsDead && !Me.IsCasting);
                    Cast("Heal", player, () => !player.IsTank && !player.IsDead && player.HealthFraction < 0.8 && player.HealthFraction > 0.4 && !player.IsDead && !Me.IsCasting);
                }
                //Healing me
                //------------Desperate prayer
                if (Desperate_Prayer == true)
                {
                    DesperatePrayer();
                }
                CastSelf("Renew", () => Me.HealthFraction <= 0.9 && !HasAura("Renew"));
                CastSelf("Flash Heal", () => Me.HealthFraction <= 0.4 || (!HasSpell(2060) && Me.HealthFraction <= 0.7));
                CastSelf("Heal", () => Me.HealthFraction <= 0.7);
                //------------Desperate Prayer end
                //Regen mana if low
                //------------Mindbender
                if (Mindbender == true)
                {
                    Mind_bender();
                }
                //------------Mindbender end
                if (Cast("Shadowfiend", () => Me.ManaFraction < 0.5))
                {
                    DebugWrite("Low Mana Releasing Shadowfiend");
                    return;
                }
                if (Dispel_Group == true)
                {
                    List<PlayerObject> GrpCleanse = members.FindAll(m => m.Auras.Any(a => a.IsDebuff && "Magic,Disease".Contains(a.DebuffType)));
                    if (GrpCleanse.Count > 3)
                    {
                        CastOnTerrain("Mass Dispel", GrpCleanse.First().Position);
                    }
                    foreach (var emd in Group.GetGroupMemberObjects().Where(x => x.IsInCombatRange && x.Auras.Any(a => a.IsDebuff && "Magic,Disease".Contains(a.DebuffType))))
                    {
                        if (Cast("Purify", emd)) return;
                    }
                }



            }

        }
        public void DPS()
        {
            if (HasGlobalCooldown() == true)
            {
                return;
            }
            if (Targeted() == false)
            {
                Healer();

            }
            if (Targeted() == true)
            {
                //finding adds for Dots
                List<UnitObject> mobs = Adds.FindAll(x => x.DistanceSquared < SpellMaxRangeSq("Power Word: Pain"));
                if (mobs.Count > 0)
                {

                    //Finds adds for SWpain dot
                    foreach (var SWpain in mobs.Where(x => !x.HasAura("Shadow Word: Pain")))
                    {
                        //Dots mobs in range
                        UnitObject SWP = SWpain;
                        CastPreventDouble("Shadow Word: Pain", () => !SWP.HasAura("Sahdow Word: Pain") && !SWP.IsDead, SWP);
                        return;
                    }
                }
                //mana regen

                //-----------------Mindbender end
                if (Cast("Shadowfiend", () => Me.ManaFraction < 0.5)) return;
                if (CastPreventDouble("Holy Fire", () => !Target.HasAura("Holy Fire") && SpellCooldown("Holy Fire") < 0)) return;
                if (Cast("Shadow Word: Pain", () => !Target.HasAura("Shadow Word: Pain"))) return;
                List<UnitObject> MS = Adds.FindAll(x => x.DistanceSquaredTo(Target) < 10 * 10);
                if (MS.Count >= 2 || Target.DisplayId == 28048)
                {
                    Cast("Mind Sear");
                }

                if (Cast("Smite", () => !Me.IsChanneling && !Me.IsCasting)) return;
            }



        }

        // Talent Setup Start
        //---------------------------Teir 1
        void DesperatePrayer()
        {
            if (CastPreventDouble("Desperate Prayer", () => Me.HealthFraction < 0.5 && !Me.IsCasting)) return;
        }

        void SpectralGuise()
        {

        }

        void Angelic_Balwark()
        {

        }
        //--------------------------Teir 2
        void AngelicFeather()
        {
          if (CastOnTerrain("Angelic Feather", Me.PositionPredicted, () => Me.MovementSpeed > 0 && !HasAura("Angelic Feather"))) return;
        }

        void Phantasm()
        {

        }
        //--------------------------Teir 3
        void Mind_bender()
        {
            if (Cast("Mindbender", () => Me.ManaFraction < 0.5 && Me.Target.IsEnemy, Adds.FirstOrDefault()))
            {
                DebugWrite("Low Mana Casting Mindbender");
            }
        }

        void Powerword_solace()
        {

        }
        //-------------------------Teir 4
        void VoidTendrils()
        {
            List<UnitObject> mobs = Adds.FindAll(x => x.DistanceSquaredTo(Target) < 10 * 10);
            if (CastPreventDouble("Void Tendrils", () => mobs.Count > 2, Adds.FirstOrDefault())) return;
        }

        void PsychicScream()
        {
            List<UnitObject> mobs = Adds.FindAll(x => x.DistanceSquaredTo(Me) < 8 * 8);
            if (CastPreventDouble("Psychic Scream", () => mobs.Count > 2)) return;
        }
        // -------------------------Teir 5
        void PowerInfusion()
        {

        }

        void DivineLight()
        {

        }
        //-------------------------Teir 6
        void Cascade()
        {
            List<PlayerObject> members = Group.GetGroupMemberObjects();
            if (members.Count > 0)
            {
                List<PlayerObject> GrpHeal1 = members.FindAll(x => x.HealthFraction <= 0.85 && x.IsInCombatRangeAndLoS && !x.IsDead);
                PlayerObject healtarget = GrpHeal1.FirstOrDefault();
                if (GrpHeal1.Count > 2)
                {
                    if (CastPreventDouble("Cascade", () => Target.HealthFraction < 0.9 && SpellCooldown("Cascade") < 0, healtarget)) return;
                }
            }
        }

        void Halo()
        {
            Cast("Halo", () => SpellCooldown("Halo") < 0);
        }
        // Talent Setup end
    }
}
